package com.yangjun.common.excel;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import com.yangjun.utils.POIExcelUtils;
import com.yangjun.utils.ReflectUtil;

public class ExcelImport extends AbstractExcelResolver{

	public ExcelImport(ExcelDefinitionReader definitionReader) {
		super(definitionReader);
	}
	/**
	 * @Description 读取Excel信息
	 * @param id
	 * @param titleIndex
	 * @param excelStream
	 * @param sheetIndex
	 * @param multivalidate
	 * @return
	 * @author yangjun
	 * @Date 2017年6月15日 上午11:14:11
	 */
	public ExcelImportResult readExcel(String id,int titleIndex,InputStream excelStream,Integer sheetIndex){
		//从注册信息中获取Bean的信息
		ExcelDefinition excelDefinition = definitionReader.getRegistry().get(id);
		if(excelDefinition==null){
			throw new ExcelException("没有找到 ["+id+"] 的配置信息");
		}
		return doReadExcel(excelDefinition,titleIndex,excelStream,sheetIndex);
	}
	
	protected ExcelImportResult doReadExcel(ExcelDefinition excelDefinition,int titleIndex,InputStream excelStream,Integer sheetIndex){
		Workbook workbook = null;
		ExcelImportResult result = null;
		try {
			workbook = WorkbookFactory.create(excelStream);
			result = new ExcelImportResult();
			//读取sheet,sheetIndex参数优先级大于ExcelDefinition配置sheetIndex
			Sheet sheet = workbook.getSheetAt(sheetIndex==null?excelDefinition.getSheetIndex():sheetIndex);
			//获取标题
			List<String> titles = readTitle(excelDefinition,sheet,titleIndex);
			//获取Bean
			List<Object> listBean = readRows(result.getErrors(),excelDefinition,titles, sheet,titleIndex);
			result.setListBean(listBean);
		} catch (Exception e) {
			
		} 
		return result;
	}
	protected List<String> readTitle(ExcelDefinition excelDefinition, Sheet sheet,int titleIndex){
		//获取标题数据
		Row TitleRow = sheet.getRow(titleIndex);
		int cellNum = TitleRow.getLastCellNum();
		List<String> titles = new ArrayList<String>(cellNum);
		for(int i=0;i<cellNum;i++){
			Cell cell = TitleRow.getCell(i);
			Object value = POIExcelUtils.getCellValue(cell);
			if(value==null){
				throw new ExcelException("id 为:["+excelDefinition.getId()+"]的标题不能为[ null ]");
			}
			titles.add(value.toString());
		}
		return titles;
	}
	
	protected <T> List<T> readRows(List<ExcelError> errors,ExcelDefinition excelDefinition, List<String> titles, Sheet sheet,int titleIndex)throws Exception {
		int rowNum = sheet.getLastRowNum();
		//读取数据的总共次数
		int totalNum = rowNum - titleIndex;
		int startRow =  -titleIndex;
		List<T> listBean = new ArrayList<T>(totalNum);
		for (int i = titleIndex+1; i <= rowNum; i++) {
			Row row = sheet.getRow(i);
			Object bean = readRow(errors,excelDefinition,row,titles,startRow+i);
			listBean.add((T) bean);
		}
		return listBean;
	}
	protected Object readRow(List<ExcelError> errors,ExcelDefinition excelDefinition, Row row, List<String> titles,int rowNum) throws Exception {
		//创建注册时配置的bean类型
		Object bean = ReflectUtil.newInstance(excelDefinition.getClazz());
		for(FieldValue fieldValue : excelDefinition.getFieldValues()){
			String title = fieldValue.getTitle();
			for(int j=0;j<titles.size();j++){
				if(title.equals(titles.get(j))){
					try{
						Cell cell = row.getCell(j);
						//获取Excel原生value值
						Object value = POIExcelUtils.getCellValue(cell);
						if(value == null || StringUtils.isBlank(value.toString())){
							//空校验
							if(!fieldValue.isNull()){
								String err = getErrorMsg(fieldValue, "不能为空", rowNum);
								throw new ExcelException(err);
							}
						}
						if(value != null){
							if(value instanceof String){
								//去除前后空格
								value = value.toString().trim();
							}
							value = super.convert(bean,value, fieldValue, Type.IMPORT,rowNum);
							ReflectUtil.setProperty(bean, fieldValue.getName(), value);
						}
					}catch(Exception e){
						errors.add(new ExcelError(rowNum,e.getMessage()));
						continue;
					}
				}
			}
		}
		return bean;
	}

}
